package callForPapers;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import notas.Nota;
import sistema.AreaDeInteres;
import sistema.Mail;
import sistema.Usuario;
import estadosPaper.Estado;
import estadosPaper.SinRevisar;

public class Paper {

	private Usuario autor;
	private Set<AreaDeInteres> areasDeInteres;
	private Estado estado;
	private List<Nota> notas;
	private Set<Usuario> revisores;
	private String titulo;
	private String resumen;
	private String pdf;

	// ////////////////////////////////////////////////////////////////////////////

	// contructor

	/**
	 * Constructor basico sin autor, ni areas de interes especificas, ni
	 * revisores
	 */
	public Paper() {
		this.areasDeInteres = new HashSet<AreaDeInteres>();
		this.estado = new SinRevisar(this);
		this.notas = new ArrayList<Nota>();
		this.revisores = new HashSet<Usuario>();
	}

	/**
	 * Constructor basico Con autor, sin areas de interes especificas, ni
	 * revisores
	 */
	public Paper(Usuario autor) {
		this.autor = autor;
		this.areasDeInteres = new HashSet<AreaDeInteres>();
		this.estado = new SinRevisar(this);
		this.notas = new ArrayList<Nota>();
		this.revisores = new HashSet<Usuario>();

	}

	/**
	 * Constructor basico con autor y un area de interes,sin revisores
	 */
	public Paper(Usuario autor, AreaDeInteres areaInteres) {
		this.autor = autor;
		this.areasDeInteres = new HashSet<AreaDeInteres>();
		this.areasDeInteres.add(areaInteres);
		this.estado = new SinRevisar(this);
		this.notas = new ArrayList<Nota>();
		this.revisores = new HashSet<Usuario>();

	}

	/**
	 * Constructor completo con autor y con una lista de areas de interes,sin
	 * revisores
	 */
	public Paper(Usuario autor, Set<AreaDeInteres> areasInteres) {
		this.autor = autor;
		this.areasDeInteres = new HashSet<AreaDeInteres>();
		this.areasDeInteres.addAll(areasInteres);
		this.estado = new SinRevisar(this);
		this.notas = new ArrayList<Nota>();
		this.revisores = new HashSet<Usuario>();

	}

	// ///////////////////////////////////////////////////////////////////////////////

	// getters y setters

	public Usuario getAutor() {
		return this.autor;
	}

	public void setAutor(Usuario autor) {
		this.autor = autor;
	}

	public Set<AreaDeInteres> getAreasDeInteres() {
		return this.areasDeInteres;
	}

	public void setAreasDeInteres(Set<AreaDeInteres> areasDeInteres) {
		this.areasDeInteres = areasDeInteres;
	}

	public Estado getEstado() {
		return this.estado;
	}

	public void setEstado(Estado estado) {
		this.estado = estado;
	}

	public List<Nota> getNotas() {
		return this.notas;
	}

	public void setNotas(List<Nota> notas) {
		this.notas = notas;
	}

	public Set<Usuario> getRevisores() {
		return this.revisores;
	}

	public void setRevisores(Set<Usuario> revisores) {
		this.revisores = revisores;
	}

	public String getTitulo() {
		return this.titulo;
	}

	public void setTitulo(String titulo) {
		this.titulo = titulo;
	}

	public String getResumen() {
		return this.resumen;
	}

	public void setResumen(String resumen) {
		this.resumen = resumen;
	}

	public String getPdf() {
		return this.pdf;
	}

	public void setPdf(String pdf) {
		this.pdf = pdf;
	}

	// /////////////////////////////////////////////////////////////////////////////////

	// metodos

	/**
	 * true si el parametro tiene al menos 1 area en comun con el paper
	 * 
	 * @param cfp
	 * @return
	 */
	public boolean tieneAreaEnComun(CallForPaper cfp) {

		for (AreaDeInteres areaPaper : this.getAreasDeInteres()) {
			if (areaPaper.isIncluded(cfp.getAreasDeInteres())) {
				return true;
			}
		}
		return false;
	}

	public void agregarRevisor(Usuario revisor) {
		this.getRevisores().add(revisor);
	}

	public void agregarNota(Nota nota) {
		this.estado.agregarNota(nota);
	}

	public void agregarNotaDesdeEstado(Nota nota) {
		this.notas.add(nota);
	}

	public void calcularNotaFinal() {
		this.getEstado().calcularNotaFinal();
	}

	public void mandarMailRevisores() {
		for (Usuario usuarioActual : this.getRevisores()) {
			this.prepararMailRevisores(usuarioActual).send();
		}
	}

	private Mail prepararMailRevisores(Usuario usuario) {
		return new Mail(usuario.getEmail(),
				"Ud ha sido selecionado para revisar el paper "
						+ this.getTitulo(), "Este es el resumen del paper: "
						+ this.getResumen(), this.getPdf());
	}

	public void mandarMailAutor() {
		this.prepararMailAutor(this.getAutor()).send();

	}

	private Mail prepararMailAutor(Usuario usuario) {

		return new Mail(usuario.getEmail(), "Su paper ha sido "
				+ this.estado.getDescripcion(), "Su paper " + this.getTitulo()
				+ "ha sido" + this.estado.getDescripcion(), this.getPdf());

	}

	public Map<String, String> verNotasYComentarios() {
		return this.getEstado().verNotasYComentarios();
	}

	public boolean esAutor(Usuario autor) {
		return this.getAutor().equals(autor);
	}

	public boolean esRevisor(Usuario revisor) {
		return this.getRevisores().contains(revisor);
	}
}
